
import os
import sys

os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
sys.path.insert(0,'../')

from testmodels.testmodel import *
import datetime
import decimal
import unittest

from mongomodel.mongodb.base import MongodbCursorWrapper
MongodbCursorWrapper.DEBUG = True

class MongoModelTest(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    def test_Constants(self):
        try:
            cons = Constants.objects.get(key='user.level')
        except Constants.DoesNotExist:
            cons = Constants(key='user.level', data={ 'basic':'Basic User', 'premimum':'Premimum User' }, description='User Level' )
            cons.save()

        print cons.data
        self.assertEquals( dict, type(cons.data) )

        try:
            cons = Constants.objects.get(key='user.max')
        except Constants.DoesNotExist:
            cons = Constants(key='user.max' )
            cons.value = 10
            cons.save()

        print cons.value

        self.assertEquals( 10, cons.value )
        self.assertEquals( int, type(cons.value) )

    def test_Embedded(self):

        #Poll.objects.filter( {"writer.name" : 'min'} )

        p = Poll(name='xxsss', question= 'What is your', pub_date=datetime.datetime.utcnow(), release_date = datetime.date.today()  )
        writer = Writer(name='min', email='miniway@gmail.com' )

        p.writer = writer
        p.time_list = [ datetime.time(13,5,6),'19:02:45' ]
        p.save()


        poll = Poll.objects.get( _id = p._id )
        self.assertEquals( Writer, type(p.writer) )
        self.assertEquals( None, poll.targets )
        print poll.as_dict(True)

        target = Target(name='target1', url='http://yahoo.com' )

        poll.writer = target
        self.assertRaises( models.exceptions.ValidationError, poll.save )

        poll.targets =target
        self.assertRaises( models.exceptions.ValidationError, poll.save )

        poll = Poll.objects.get( _id = p._id )
        #poll.writer = writer
        poll.targets = [target]
        poll.save()

        poll = Poll.objects.get( _id = p._id )
        self.assertEquals( Target, type(poll.targets[0]) )



        self.assertEquals( 2, len( poll.time_list ))
        self.assertEquals( datetime.time, type(poll.time_list[0] ))


        print Poll.objects.filter( writer = {'name':'min'} )
        print Poll.objects.filter( targets = {'name':'target2'} )
        print Poll.objects.filter( targets = {'name':'target1'}, question__startswith='What' )
        #print p._id , p.question, p.release_date, type(p.release_date), p.num_stars, p.f_value , type(p.f_value), p.gender

    def test_Search(self):

        p = Poll(name='xxsss', question= 'What is your', pub_date=datetime.datetime.utcnow(), release_date = datetime.date.today()  )
        p.save()

        length = len(Poll.objects.all())
        cnt = Poll.objects.all().count()
        self.assertTrue( length > 0 )
        self.assertEquals( length, cnt )

        poll = Poll.objects.all()[0]
        self.assertEquals( Poll.objects.filter(_id= poll._id )[0], Poll.objects.get(_id= poll._id ) )
        
        rows = Poll.objects.filter(question__startswith='What').order_by('-_id')
        self.assertTrue( rows.count() > 1 ) 

        prev = None
        for r in rows:
            if not prev :
                prev = r._id
                continue

            self.assertTrue( prev > r._id )
            prev = r._id

        values = Poll.objects.filter(question__startswith='What').order_by('_id','-question').values('question','pub_date')

        self.assertEquals( dict, type(values[0] ))
        for p in Poll.objects.filter(pub_date__year=2010):
            self.assertEquals( 2010, p.pub_date.year )
        for p in Poll.objects.filter(pub_date__month=9):
            self.assertEquals( 9, p.pub_date.month )
        for p in Poll.objects.filter(pub_date__day=8):
            self.assertEquals( 8, p.pub_date.day )
        for p in Poll.objects.filter(question__contains='is'):
            self.assertTrue( p.question.find('is') > 0 )
        for p in Poll.objects.exclude(question__contains='iis'):
            self.assertTrue( p.question.find('iis') < 0 )
        for p in Poll.objects.filter(question__iexact='what is your'):
            self.assertTrue( 'what is your', p.question.lower() )
        self.assertEquals( 0, Poll.objects.filter(question__isnull=True).count() )

        for p in Poll.objects.filter(question__startswith='What') \
                    .exclude( pub_date__lte=datetime.datetime.utcnow())\
                    .filter( pub_date__gte=datetime.datetime(2005, 1, 1) ) :
            print p

        c = p.choice_set.create(choice='Not much', votes=0)
        self.assertTrue( p.choice_set.all().count() > 0 )

        self.assertEquals( p, c.poll  )
        for c in Choice.objects.filter(poll__pub_date__year=2010):
            self.assertEquals( 2010, c.poll.pub_date.year )
        for c in p.choice_set.filter(choice__startswith='Not'):
            self.assertTrue( c.choice.startswith('Not' ) )


        id = c._id
        c.delete()

        self.assertRaises( Choice.DoesNotExist, Choice.objects.get, _id = id )

        p = Poll.objects.all()[0]
        p.delete()

        self.assertEquals( 0, Choice.objects.filter( poll = p ).count() )

        from django.db.models import F, Q
        p = Poll.objects.all()[0]
        p.n_comments = 5
        p.n_pingbacks = 1
        p.writer = Writer(name='hello', email='hello@mail.com')
        p.save()

        c = Poll.objects.filter(n_comments__gt=F('n_pingbacks'))
        list(c)
        c = Poll.objects.filter(n_comments__gt=F('n_pingbacks')*2)
        list(c)
        c = Poll.objects.filter(n_comments__gt=F('n_pingbacks')+F('n_comments'))
        list(c)
        c = Poll.objects.filter(n_comments__gt=F('n_pingbacks')+F('choice__votes'))
        list(c)
        c =Poll.objects.filter(
            Q(question__startswith='What'),
            Q(pub_date=datetime.date(2005, 5, 2)) | Q(pub_date=datetime.date(2005, 5, 6))
            )
        list(c)
        c = Poll.objects.filter(
            Q(pub_date=datetime.date(2005, 5, 2)) | Q(pub_date=datetime.date(2005, 5, 6)),
            question__startswith='Who')
        list(c)

    def test_Raw(self):
        raw_qs = Poll.objects.raw( 'find',{'writer.name':'min'} ) 
        print raw_qs.count()
        for p in raw_qs:
            print p.writer.name, p.n_comments
        Poll.objects.raw( 'update',{'writer.name':'min'}, {'$inc':{'n_comments':1}}  ) 

    def test_Aggregate(self):
        from django.db.models import Count,Avg,Max,Min,Sum
        
        q = Poll.objects.aggregate(Count('_id'))
        print q
        q = Poll.objects.aggregate(Avg('n_comments'))
        print q
        q = Poll.objects.aggregate(average_price=Avg('n_comments'))
        print q
        q = Poll.objects.aggregate(Max('n_comments'))
        print q
        q = Poll.objects.aggregate(Min('n_comments'))
        print q
        q = Poll.objects.aggregate(Avg('n_comments'),Max('n_comments'),Min('n_comments'))
        print q
        q = Poll.objects.aggregate(Sum('n_comments'))
        print q
        #q = Poll.objects.annotate(Count('choice'))
        #print q[0]

if __name__ == "__main__":

    #For sinlge method test
    suite = unittest.TestSuite()


    #suite.addTest(MongoModelTest("test_Constants"))
    #suite.addTest(MongoModelTest("test_Embedded"))
    #suite.addTest(MongoModelTest("test_Raw"))
    #suite.addTest(MongoModelTest("test_Search"))
    #suite.addTest(MongoModelTest("test_Aggregate"))

    if not suite._tests:
        suite = unittest.makeSuite(MongoModelTest)

    unittest.TextTestRunner(verbosity=2).run(suite)
